/**
 * 
 */
package com.itboye.allshengmedical.sci.packet.req;

import com.itboye.allshengmedical.sci.cmd.req.CmdType;

/**
 * 请求数据的基类
 * @author 贝贝 346551990@qq.com
 * @date   2016-12-8 
 */
public class BaseReqPacket {
	
	/**
	 * 转换成bytes
	 * @return
	 */
	public byte[] toBytes(){
		byte[] bytes = new byte[start.length + end.length + 1 + content.length + checkBit.length];
		int bytesIndex = 0;
        System.arraycopy(start , 0, bytes, bytesIndex, start.length);  
        bytes[start.length] = len;
        bytesIndex += start.length+1;
        System.arraycopy(content , 0 , bytes , bytesIndex , content.length);
        bytesIndex += content.length;
        System.arraycopy(checkBit , 0 , bytes , bytesIndex , checkBit.length); 
        bytesIndex += checkBit.length;
        System.arraycopy(end, 0, bytes, bytesIndex  , end.length);
        
        return bytes;
	}
	 
	
	//例子数据
	
	//start len content  checkBit  end
	// ↓↓    ↓↓    ↓↓     ↓↓        ↓↓
	//5AA5   04 01000000 0102      3EE3
	
	@Override
	public String toString() {
		return  bytesToHexString(start)  + bytesToHexString(len) + bytesToHexString(content) + bytesToHexString(checkBit)+ bytesToHexString(end);
	}
	
	private String bytesToHexString(byte src){

		StringBuilder stringBuilder = new StringBuilder("");
        int v = src & 0xFF;  
        String hv = Integer.toHexString(v);  
        if (hv.length() < 2) {  
            stringBuilder.append(0);  
        }  
        
        return stringBuilder.append(hv).toString();  
	}
	
	private String bytesToHexString(byte[] src){
		StringBuilder stringBuilder = new StringBuilder("");
	    if (src == null || src.length <= 0) {
	       return null;  
	    }
	    
	    for (int i = 0; i < src.length; i++) {  
	        int v = src[i] & 0xFF;  
	        String hv = Integer.toHexString(v);  
	        if (hv.length() < 2) {  
	            stringBuilder.append(0);  
	        }  
	        stringBuilder.append(hv);  
	    }
	    
	    return stringBuilder.toString();  
	}  
	
	
	private byte[]   start;//起始字符5AA5
	private byte[]   end;//结束字符 3EE3
	private byte 	 len;//数据长度 0xFF
	private byte[]   content;//数据读取的内容
	private byte[]   checkBit;//校验位
	private CmdType  cmdType;//数据包类型=》根据数据内容第一个字节生成
	
	
	/**
	 * 计算校验位
	 */
	public void calCheckBit(){
		
		int sum = this.sumLenAndContent();
		
		if(this.checkBit == null){
			this.checkBit = new byte[2];
		}
		
		this.checkBit[0] = (byte)((sum >> 8) & 0xFF); 
		this.checkBit[1] = (byte)(sum  & 0xFF);
	}
	
	/**
	 * 求和
	 * @return
	 */
	private int sumLenAndContent(){
		int sum = 0 + len;
		
		for ( int i = 0 ; i < this.content.length ; i++){
			sum += this.content[i];
		}
		
		return sum;
	}
	
	/**
	 * 验证校验位
	 * @return
	 */
	public boolean isValidPack(){
		
		if(this.checkBit == null){
			return false;
		}
		
		int sum = this.sumLenAndContent();
		int sumCompare = this.checkBit[0] + this.checkBit[1];
		
		return sum == sumCompare;
	}

	public byte[] getStart() {
		return start;
	}

	public void setStart(byte[] start) {
		this.start = start;
	}

	public byte[] getEnd() {
		return end;
	}

	public void setEnd(byte[] end) {
		this.end = end;
	}

	public byte getLen() {
		return len;
	}

	public void setLen(byte len) {
		this.len = len;
	}

	public void setContent(int index,byte bt){
		this.content[index] = bt;
	}
	
	/**
	 * 
	 * @param index
	 * @return
	 */
	public byte getContent(int index) {
		
		if(this.content != null && this.content.length > index && this.content.length == (int) this.len){
			return content[index];
		}
		
		return 0;
	}
	
	public byte[] getContent() {
		return content;
	}

	public void setContent(byte[] content) {
		this.content = content;
		if(this.content != null && this.content.length > 1){
			setCmdType(CmdType.getCmdType(content[0]));
		}
	}

	public byte[] getCheckBit() {
		return checkBit;
	}


	/**
	 * @return the cmdType
	 */
	public CmdType getCmdType() {
		return cmdType;
	}


	/**
	 * @param cmdType the cmdType to set
	 */
	public void setCmdType(CmdType cmdType) {
		this.cmdType = cmdType;
	} 
	
}
